package edu.wpi.cs509.ui;

import java.awt.*;
import java.awt.image.*;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.*;

import edu.wpi.cs509.representation.PlayerPiece;

public class GameBoardPanel extends JPanel {

	private static final long serialVersionUID = 1L;
	
	private int rows, cols;

    private BufferedImage origImg;
    private BufferedImage scaledImg;
    
    public GameBoardSquare from,to;
    
    /**
     * Constructor for a GameBoardPanel object
     * 
     * The board is allowed to be whatever size grid is specified.  Typically
     * Stratego is a 10x10 grid.
     * 
     * The resolution of the board image will determine the preferred size
     * for the this graphics container.
     * 
     * @param rows - the number of rows in the game board
     * @param cols - the number of columns in the game board
     * @param initevent 
     */
    public GameBoardPanel( int rows, int cols, GameBoardNotify initevent ) {
    	
    	this.rows = rows;
    	this.cols = cols;
    	
    	try {

			GridLayout gameGrid = new GridLayout( rows, cols );
			setLayout( gameGrid );
			
			GameBoardSquare square = null;
			for (int i=0; i<rows; i++) {
				for (int j=0; j<cols; j++) {
					square = new GameBoardSquare(i,j,this,initevent);
					square.setLayout( new BorderLayout() );
					add(square, BorderLayout.CENTER);
				}
			}
			
			Dimension squareDim;
			if (square != null) {
				squareDim = square.getPreferredSize();
			} else {
				squareDim = new Dimension(10,10);
			}
    	    
			int width = (int) (squareDim.getWidth()*cols);
			int height = (int) (squareDim.getHeight()*rows);
			Dimension boardDim = new Dimension( width, height );
			
	    	setPreferredSize( boardDim );			

			try {
				origImg = ImageIO.read(getClass().getResourceAsStream("/edu/wpi/cs509/ui/images/Classic_board_2.jpg"));
			} catch (IOException e1) {
				e1.printStackTrace();
			}
				    	
		} catch (Exception e) {
			System.err.println("Could not find board.");
		e.printStackTrace();
		}
    	
    	setVisible(true);
    }
 
    /**
     * Examines the current dimensions of the component and resizes the
     * game board graphic to fit.  This routine does not enforce that 
     * the grid remains square.
     */
    private void scaleBoardImage() {

    	 int w = origImg.getWidth();  
    	 int h = origImg.getHeight(); 
    	 
    	 Dimension contentArea = getSize();

    	 int newW = (int) contentArea.getWidth();
    	 int newH = (int) contentArea.getHeight();
    	 
    	 scaledImg = new BufferedImage(newW, newH, origImg.getType());  
    	 
    	 Graphics2D g = scaledImg.createGraphics();  
    	 g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);  
    	 g.drawImage(origImg, 0, 0, newW, newH, 0, 0, w, h, null);  
    	 g.dispose();
    	 
    }
    
    /**
     * Redraws the scaled game board image in the graphics container
     * 
     * @param g - the graphics context used to draw this component
     */
	public void paintComponent(Graphics g) {       
		scaleBoardImage();		
        g.drawImage(scaledImg, 0, 0, null);
    }
	
	public void redrawBoard(){
        for(int i=0;i<this.getComponentCount();i++){
        	GameBoardSquare s = (GameBoardSquare) this.getComponent(i);
        	s.repaint();
        }
	}
	/**
	 * Retrieves the graphic width of the board square 
	 * 
	 * @return  the width of a board square in pixels
	 */
	public int getBoardSquareWidth() {
		Dimension contentArea = getSize();
		return (int)contentArea.getWidth()/cols;
	}

	/**
	 * Retrieves the graphic height of the board square 
	 * 
	 * @return  the height of a board square in pixels
	 */
	public int getBoardSquareHeight() {
		Dimension contentArea = getSize();
		return (int)contentArea.getHeight()/rows;
	}
	/**
	 * Returns the index of the board square as seen by the GUI.
	 * @param square
	 * @return the index of the board square
	 */
    public int getBoardSquareIndex(GameBoardSquare square){
    	for(int i=0;i<rows*cols;i++){
    		if((GameBoardSquare) this.getComponent(i) == square){
    			return i;
    		}
    	}
    	return rows*cols;
    }

    public GameBoardSquare getGameBoardSquare( int index ) {
    	return (GameBoardSquare)this.getComponent(index);
    }
    
    public void gameStarted(GameBoardNotify event) {
    	for (int n = 0; n < rows * cols; n++) {
			GameBoardSquare square = (GameBoardSquare)this.getComponent(n);
			square.changeMouseAdapter(event);
		}
    }

	public void movePiece( PlayerPiece piece, int from, int to) {
		System.out.println("movePiece has been called");
		GameBoardSquare fromSquare = (GameBoardSquare)getComponent(from);
		GameBoardSquare   toSquare = (GameBoardSquare)getComponent(to);

		fromSquare.blink( 8 );
		fromSquare.removePiece();
		toSquare.blink( 16 );
		toSquare.addPiece(piece);
	}
	
	public void removePiece(int pieceIdx) {
		System.out.println("removePiece has been called");
		GameBoardSquare square = (GameBoardSquare)getComponent(pieceIdx);
		square.removePiece();
		repaint();
	}
}